package cn.yeziji.forum.dao.impl;

import cn.yeziji.forum.annoataion.SaveCache;
import cn.yeziji.forum.common.ForumPageResult;
import cn.yeziji.forum.common.key.QuestionCacheKey;
import cn.yeziji.forum.converter.QuestionConverter;
import cn.yeziji.forum.dao.base.ForumQuestionBaseDao;
import cn.yeziji.forum.dao.intf.ForumQuestionDao;
import cn.yeziji.forum.dao.intf.ForumUserDao;
import cn.yeziji.forum.dao.iquery.QuestionQuery;
import cn.yeziji.forum.dao.iupdater.QuestionUpdater;
import cn.yeziji.forum.dto.question.QuestionDTO;
import cn.yeziji.forum.dto.question.QuestionPagingDTO;
import cn.yeziji.forum.entity.ForumQuestionEntity;
import cn.yeziji.forum.exception.QuestionException;
import cn.yeziji.forum.common.enums.status.QuestionStatus;
import cn.yeziji.forum.utils.JwtOperaUtils;
import cn.yeziji.forum.vo.question.QuestionVO;
import cn.yeziji.forum.vo.user.UserMsgVO;
import org.springframework.stereotype.Repository;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.Map;

/**
 * 提问问题实现业务逻辑层
 *
 * @author gzkemays
 * @since 2022/11/12 4:47 PM
 */
@Repository
public class ForumQuestionDaoImpl extends ForumQuestionBaseDao implements ForumQuestionDao {
  @Resource HttpServletRequest request;

  @Resource ForumUserDao userDao;

  @Override
  public void submit(QuestionDTO dto) {
    ForumQuestionEntity entity = dto.createEntity();
    Integer userId = JwtOperaUtils.getUserIdByRequest(request);
    if (userId != null) {
      entity.setUserId(userId);
    } else {
      throw new QuestionException(QuestionStatus.QUESTION_SUBMIT_FAIL);
    }
    save(entity);
  }

  @Override
  public void adopted(QuestionDTO dto) {
    ForumQuestionEntity adoptedEntity = dto.adoptedEntity();
    ForumQuestionEntity entity = selectById(adoptedEntity.getId());
    if (entity != null && entity.getAnswerId() != null) {
      throw new QuestionException(QuestionStatus.QUESTION_ADOPTED_FAIL);
    }
    updateById(dto.adoptedEntity());
  }

  @Override
  @SaveCache(
      value = {QuestionCacheKey.QUESTION_LIST},
      joinery = "::",
      jsonKey = {"userId", "page", "content"})
  public ForumPageResult<QuestionVO> list(QuestionPagingDTO pagingDTO) {
    Integer userId = JwtOperaUtils.getUserIdIfZero(request);
    pagingDTO.setUserId(userId);
    List<Map<String, Object>> maps =
        mapper.listMaps(QuestionQuery.blurTitleOrContentPagingQuery(pagingDTO));
    pagingDTO.total(mapper().count(QuestionQuery.blurTitleOrContentQuery(pagingDTO)));
    List<QuestionVO> questionVOS = QuestionConverter.INSTANCE.mapsConvertToVOs(maps);
    for (QuestionVO questionVO : questionVOS) {
      String nickname = questionVO.getNickname();
      UserMsgVO userMsg = userDao.getUserMsg(nickname);
      questionVO.setAuthor(userMsg);
    }
    return new ForumPageResult<>(questionVOS, pagingDTO);
  }

  @Override
  public QuestionVO getQuestionById(Integer id) {
    Integer userIdIfZero = JwtOperaUtils.getUserIdIfZero(request);
    Map<String, Object> map =
        mapper
            .findOneMap(QuestionQuery.getQuestionDetailQuery(id, userIdIfZero))
            .orElseThrow(() -> new QuestionException(QuestionStatus.QUESTION_IS_NOT_FOUND));
    Object questionId = map.get("id");
    if (questionId != null) {
      updateBy(QuestionUpdater.updateViewUpdater((Integer) questionId));
    }
    return QuestionConverter.INSTANCE.mapConvertToVOs(map);
  }

  @Override
  public List<ForumQuestionEntity> getUser7DaysQuestions(Integer userId) {
    return mapper.listEntity(QuestionQuery.getUser7DaysQuestionsQuery(userId));
  }
}
